package com.gxm.base.grammar_运算语法.位移;

import org.junit.Test;

public class Demo {

    @Test
    public void test01(){
        int xx = 20;
        System.out.println( xx << 1 );        //40
        /* x在内存中的二进制形式为:
            0000 0000 0000 0000 0000 0000 0001 0100
            xx<<1 左移一位
          0 0000 0000 0000 0000 0000 0000 0010 1000
        */

        System.out.println( xx >> 1 );        //10
        /* x在内存中的二进制形式为:
            0000 0000 0000 0000 0000 0000 0001 0100
            xx>>1 右移一位, 左侧补0
            0000 0000 0000 0000 0000 0000 0000 1010 0
        */

        xx = -20;
        System.out.println( xx << 1 );        //-40
        /* x在内存中的二进制形式为:
            1111 1111 1111 1111 1111 1111 1110 1100
            xx<<1 左移一位
          1 1111 1111 1111 1111 1111 1111 1101 1000
        */
        System.out.println( xx >> 1 );        //-10
        /* x在内存中的二进制形式为:
            1111 1111 1111 1111 1111 1111 1110 1100
            xx>>1 右移一位, 左侧补1
            1111 1111 1111 1111 1111 1111 1111 0110
        */

        //左移一位,相当于这个数乘以2, 右移一位,相当于这个数除以2

        xx = -11;
        System.out.println( xx << 1 );        //-22
        /* x在内存中的二进制形式为:
            1111 1111 1111 1111 1111 1111 1111 0101
            xx<<1 左移一位
          1 1111 1111 1111 1111 1111 1111 1110 1010
        */

        xx = -13;
        System.out.println( xx << 1 );        //-26
        /* x在内存中的二进制形式为:
            1111 1111 1111 1111 1111 1111 1111 0011
            xx<<1 左移一位, 右侧补0
          1 1111 1111 1111 1111 1111 1111 1110 0110
        */

        xx = -11;
        System.out.println( xx >> 1 );        //-6
        /* x在内存中的二进制形式为:
            1111 1111 1111 1111 1111 1111 1111 0101
            xx>>1 右移一位, 左侧补1
            1111 1111 1111 1111 1111 1111 1111 1010 1
        */

        xx = -13;
        System.out.println( xx >> 1 );        //-7
        /* x在内存中的二进制形式为:
            1111 1111 1111 1111 1111 1111 1111 0011
            xx>>1 右移一位, 左侧补1
            1111 1111 1111 1111 1111 1111 1111 1001 1
        */

        xx = -11;
        System.out.println( xx >>> 1 );        //2147483642
        /* x在内存中的二进制形式为:
            1111 1111 1111 1111 1111 1111 1111 0101
            xx>>>1 无符号移一位
            0111 1111 1111 1111 1111 1111 1111 1010 1
        */

        //一个整数乘以/除以2的幂次方时,通过移位运算效率最高
    }

    @Test
    public void test02(){
        int x = 10;
        int y = 20;
        /*按位与
            x在计算机中存储的01序列为:
                0000 0000 0000 0000 0000 0000 0000 1010
            y的二进制形式为:
                0000 0000 0000 0000 0000 0000 0001 0100
        按位与&
            ----------------------------------------------
                0000 0000 0000 0000 0000 0000 0000 0000
        */
        System.out.println( x&y );          //0

        /*按位或
            x在计算机中存储的01序列为:
                0000 0000 0000 0000 0000 0000 0000 1010
            y的二进制形式为:
                0000 0000 0000 0000 0000 0000 0001 0100
        按位或|
            ----------------------------------------------
                0000 0000 0000 0000 0000 0000 0001 1110
        */
        System.out.println( x|y );          //30

        /*按位异或
            x在计算机中存储的01序列为:
                0000 0000 0000 0000 0000 0000 0000 1010
            y的二进制形式为:
                0000 0000 0000 0000 0000 0000 0001 0100
        按位异或^
            ----------------------------------------------
                0000 0000 0000 0000 0000 0000 0001 1110
        */
        System.out.println( x^y );          //30

        /*按位取反
            x在计算机中存储的01序列为:
                0000 0000 0000 0000 0000 0000 0000 1010
        按位取反
            ----------------------------------------------
                1111 1111 1111 1111 1111 1111 1111 0101
        */
        System.out.println( ~x );           //-11

        // 如何实现两个数的原地交换,  不借助于第三个变量,实现两个变量的交换
        x = 10;
        y = 20;
        //正常情况下,交换两个变量的值
        int t = x;
        x = y;
        y = t;

        //方法1:
        x = 10;
        y = 20;
        x = x + y;      //x==30
        y = x - y;      //y==10
        x = x - y;      //x==20

        //方法2:
        x = 10;
        y = 20;
        x = x ^ y;      //x==30
        y = x ^ y;      //y==10
        x = x ^ y;      //x==20
    }
}
